package com.gxar.marketdelivery.shared.utils;

import java.lang.reflect.Array;
import java.util.Collection;

/**
 * @author nice
 * @version 1.0
 * @created 2023/7/21.
 */
public class ArrayUtils extends org.apache.commons.lang3.ArrayUtils {
    /**
     * 数组长度，如果为空，则为0
     *
     * @param array
     * @return
     */
    public static int length(Object[] array) {
        if (array == null)
            return 0;
        return array.length;
    }

    /**
     * 数组长度，如果为空，则为0
     *
     * @param array
     * @return
     */
    public static int length(int[] array) {
        if (array == null)
            return 0;
        return array.length;
    }

    /**
     * 数组长度，如果为空，则为0
     *
     * @param array
     * @return
     */
    public static int length(long[] array) {
        if (array == null)
            return 0;
        return array.length;
    }

    /**
     * 两个相同类型的数组合并，得到新的数组
     *
     * @param a1
     * @param a2
     * @param <T>
     * @return
     */
    public static <T> T[] concat(T[] a1, T... a2) {
        if (a1 == null && a2 == null) {
            return null;
        }
        int length1 = length(a1);
        int length2 = length(a2);

        int newLength = length1 + length2;
        Class componentType = a1 == null ? a2.getClass().getComponentType() : a1.getClass().getComponentType();
        T[] result = (T[]) Array.newInstance(componentType, newLength);
        if (length1 > 0) {
            System.arraycopy(a1, 0, result, 0, length1);
        }
        if (length2 > 0) {
            System.arraycopy(a2, 0, result, length1, length2);
        }

        return result;
    }

    public static int[] concat(int[] a1, int... a2) {
        if (a1 == null && a2 == null) {
            return null;
        }
        int length1 = length(a1);
        int length2 = length(a2);

        int newLength = length1 + length2;
        int[] result = new int[newLength];
        if (length1 > 0) {
            System.arraycopy(a1, 0, result, 0, length1);
        }
        if (length2 > 0) {
            System.arraycopy(a2, 0, result, length1, length2);
        }

        return result;
    }

    public static long[] concat(long[] a1, long... a2) {
        if (a1 == null && a2 == null) {
            return null;
        }
        int length1 = length(a1);
        int length2 = length(a2);

        int newLength = length1 + length2;
        long[] result = new long[newLength];
        if (length1 > 0) {
            System.arraycopy(a1, 0, result, 0, length1);
        }
        if (length2 > 0) {
            System.arraycopy(a2, 0, result, length1, length2);
        }

        return result;
    }

    /**
     * 数组转化成字符串输出: 格式[a,b,c]
     *
     * @param array
     * @return
     */
    @SuppressWarnings("squid:S1994")
    public static String toString(Object[] array) {
        if (array == null || array.length == 0) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        sb.append(StringUtils.join(array, ','));
        return sb.append(']').toString();
    }

    public static String toString(int[] array) {
        if (array == null || array.length == 0) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        sb.append(StringUtils.join(array, ','));
        return sb.append(']').toString();
    }

    public static String toString(long[] array) {
        if (array == null || array.length == 0) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        sb.append(StringUtils.join(array, ','));
        return sb.append(']').toString();
    }

    /**
     * 转化成数组
     *
     * @param items
     * @param <T>
     * @return
     */
    public static <T> T[] toArray(T... items) {
        return items;
    }

    /**
     * 转化成整型数组
     *
     * @param items
     * @return
     */
    public static int[] toIntArray(int... items) {
        return items;
    }

    /**
     * 转化成Long型数组
     *
     * @param items
     * @return
     */
    public static long[] toLongArray(long... items) {
        return items;
    }

    /**
     * 集合转化成数组
     *
     * @param collection
     * @param componentType
     * @param <T>
     * @return
     */
    public static <T> T[] toArray(Collection collection, Class<T> componentType) {
        int length = collection == null ? 0 : collection.size();
        T[] result = (T[]) Array.newInstance(componentType, length);
        if (length > 0) {
            result = (T[]) collection.toArray(result);
        }
        return result;
    }

    /**
     * 数组总的位置
     *
     * @param array
     * @param objectToFind
     * @return
     */
    public static int indexOf(final Object[] array, final Object objectToFind) {
        if (length(array) == 0) {
            return -1;
        }
        int startIndex = 0;
        if (objectToFind == null) {
            for (int i = startIndex; i < array.length; i++) {
                if (array[i] == null) {
                    return i;
                }
            }
        } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
            for (int i = startIndex; i < array.length; i++) {
                if (objectToFind.equals(array[i])) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 数组总的位置
     *
     * @param array
     * @param valueToFind
     * @return
     */
    public static int indexOf(final int[] array, final int valueToFind) {
        if (length(array) == 0) {
            return -1;
        }
        int startIndex = 0;
        for (int i = startIndex; i < array.length; i++) {
            if (valueToFind == array[i]) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 数组对象的长度
     *
     * @param o
     * @return
     */
    public static int getArrayLength(Object o) {
        return getLength(o);
    }

    /**
     * 是否包含非空成员
     *
     * @param elements
     * @param <T>
     * @return
     */
    public static <T> boolean containsNotNullElement(T... elements) {
        if (isEmpty(elements)) {
            return false;
        }

        for (T e : elements) {
            if (e != null) {
                return true;
            }
        }
        return false;
    }
}
